package com.alcatel_lucent.osp.action;

import com.alcatel_lucent.osp.model.Attachment;
import com.alcatel_lucent.osp.model.Request;
import com.alcatel_lucent.osp.service.AttachmentService;
import com.alcatel_lucent.osp.service.JSONService;
import com.alcatel_lucent.osp.service.RequestService;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.SessionAware;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.File;
import java.sql.Timestamp;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * Created with IntelliJ IDEA.
 * User: Guoshun Wu
 * Date: 13-8-26
 * Time: 下午9:29
 */

@ParentPackage("osp-json")
@Result(type = "json", params = {"noCache", "true", "contentType", "text/html", "ignoreHierarchy", "false",
        "includeProperties", "message,status,attachmentsJSON.*"})
public class UploadAttachmentAction extends JSONAction implements SessionAware {

    public static final String UPLOAD_TOKEN_KEY = "uploadedAttachments";
    public static final String TRANSIENT_ATTACHMENT_ID_KEY = "transientAttachmentId";

    private File upload;
    private String contentType;
    private String fileName;

    private JSONObject attachmentsJSON;
    private Map<String, Object> session;

    private JSONService jsonService;
    private RequestService requestService;

    @Autowired
    private AttachmentService attachmentService;

    private Long id;

    public void setId(Long id) {
        this.id = id;
    }

    @Autowired
    public void setRequestService(RequestService requestService) {
        this.requestService = requestService;
    }

    @Autowired
    public void setJsonService(JSONService jsonService) {
        this.jsonService = jsonService;
    }

    public JSONObject getAttachmentsJSON() {
        return attachmentsJSON;
    }

    public void setUpload(File upload) {
        this.upload = upload;
    }

    public void setUploadContentType(String contentType) {
        this.contentType = contentType;
    }

    public void setUploadFileName(String fileName) {
        this.fileName = fileName;
    }

    @Override
    protected String performAction() throws Exception {
        log.info("upload={}, fileName={}, contentType={}", new Object[]{upload, fileName, contentType});

        BlockingQueue<Attachment> attachmentList = (BlockingQueue<Attachment>) session.get(UPLOAD_TOKEN_KEY);
        if (null == attachmentList) {
            attachmentList = new LinkedBlockingDeque<Attachment>();
        }
        Long id = (Long) session.get(TRANSIENT_ATTACHMENT_ID_KEY);
        if (null == id) {
            id = 100L;
        }

        Attachment attachment = new Attachment(fileName, upload.length(), FileUtils.readFileToByteArray(upload));
        attachment.setId(id++);

        attachmentList.add(attachment);
        attachmentsJSON = jsonService.toGridJSON(attachmentList, 100, 1, null, "id", "name, size, createTime");

        session.put(UPLOAD_TOKEN_KEY, attachmentList);
        session.put(TRANSIENT_ATTACHMENT_ID_KEY, id);
        setMessage(getText("message.success"));
        setStatus(0);
        return SUCCESS;
    }

    @Action("update-request-attachment")
    public String updateRequestAttachment() throws Exception {
        log.info("upload={}, fileName={}, contentType={}", new Object[]{upload, fileName, contentType});
        Request request = requestService.findRequestById(id);
        if (null == request) {
            setStatus(-1);
            setMessage(getText("message.fail"));
            return SUCCESS;
        }
        Attachment attachment = new Attachment(fileName, upload.length(), FileUtils.readFileToByteArray(upload));
        attachment.setRequest(request);

        attachment = attachmentService.createAttachment(attachment);
        request.setLastUpdateTime(new Timestamp(System.currentTimeMillis()));
        request.getAttachments().add(attachment);
        attachmentsJSON = jsonService.toGridJSON(request.getAttachments(), 100, 1, null, "id", "name, size, createTime");
        return SUCCESS;
    }

    @Action("upload-image")
    public String uploadImages() throws Exception {
        log.info("upload={}, fileName={}, contentType={}", new Object[]{upload, fileName, contentType});

        if(null == upload || null == fileName ){
            setStatus(-1);
            setMessage("upload or file is null");
            return SUCCESS;
        }
        Request request = requestService.findRequestById(id);
        if (null == request) {
            setStatus(-1);
            setMessage(getText("message.fail"));
            return SUCCESS;
        }
//
        String destPath = "uploadFiles/Request_" + id + "/" + fileName;
        FileUtils.copyFile(upload, new File(ServletActionContext.getServletContext().getRealPath(destPath)));

        setStatus(0);
        setMessage("cke-saved-src=" + destPath);
        return SUCCESS;
    }


    @Action("delete-attachment")
    public String deleteAttachment() throws Exception {
        log.info("id={}", id);

        BlockingQueue<Attachment> attachmentList = (BlockingQueue<Attachment>) session.get(UPLOAD_TOKEN_KEY);
        if (null == attachmentList) {
            setMessage(getText("message.fail"));
            setStatus(-1);
            return SUCCESS;
        }
        // remove attachment which id equal param id
        CollectionUtils.filter(attachmentList, new Predicate() {
            @Override
            public boolean evaluate(Object object) {
                Attachment attachment = (Attachment) object;
                return !attachment.getId().equals(id);
            }
        });

        setMessage(getText("message.success"));
        setStatus(0);
        return SUCCESS;
    }

    @Override
    public void setSession(Map<String, Object> session) {
        this.session = session;
    }
}
